<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<![endif]-->
<title>VIM 中文帮助: Vim 的各种窍门</title>
<link rel="stylesheet" href="vim-stylesheet.css" type="text/css" />
<link rel="canonical" href="https://yianwillis.github.io/vimcdoc/doc/tips.html" />
<script type="text/javascript" src="vimcdoc.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<nav id=banner>
<form action=tags.html target="tag_iframe">
  <input type="text" name="tag" id="tag" placeholder="标签搜索">
</form>
<iframe name="tag_iframe" src=""></iframe>
<a href="help.html">帮助总览</a> &middot;
<hr/>
<a href="quickref.html">快速参考</a> &middot;
<a href="index.html">命令索引</a> &middot;
<a href="eval.html#functions">函数列表</a> &middot;
<a href="quickref.html#option-list">选项列表</a> &middot;
<hr/>
<a href="usr_toc.html">用户手册</a> &middot;
<a href="help.html#reference_toc">参考手册</a> &middot;
</nav>

<header>
<h2>tips</h2>
</header>
<article id=outer>
<section class=inner>
<b class="vimtag"> <a name="tips.txt">tips.txt</a> </b>      适用于 Vim 9.0 版本。   最近更新: 2022年7月


                  <code class="vim">VIM 参考手册    by Bram Moolenaar</code>
                                <code class="vim">译者</code>: iCrazy &lt;icrazy@ustc.edu&gt;、tocer


使用 Vim 的技巧                                         <b class="vimtag"> <a name="tips">tips</a> </b>

这里只是一小部分我们认为会对很多用户有用的技巧。更多的技巧都在 wiki 上。URL 可
以从这里找到:
<a href="http://www.vim.org">http://www.vim.org</a>

别忘记浏览用户手册，里面也有很多实用的技巧  <a href="usr_toc.html#usr_toc.txt">usr_toc.txt</a> 。

编辑 C 程序                                      <a href="tips.html#C-editing">C-editing</a> 
查找使用标识符的地方                             <a href="tips.html#ident-search">ident-search</a> 
在 xterm 中切换屏幕                              <a href="tips.html#xterm-screens">xterm-screens</a> 
在插入模式下滚屏                                 <a href="tips.html#scroll-insert">scroll-insert</a> 
平滑的滚屏                                       <a href="tips.html#scroll-smooth">scroll-smooth</a> 
纠正普通的录入错误                               <a href="tips.html#type-mistakes">type-mistakes</a> 
统计单词数、行数等                               <a href="tips.html#count-items">count-items</a> 
恢复光标位置                                     <a href="tips.html#restore-position">restore-position</a> 
文件更名                                         <a href="tips.html#rename-files">rename-files</a> 
更改多个文件中的一个名字                         <a href="tips.html#change-name">change-name</a> 
加速外部命令的执行                               <a href="tips.html#speed-up">speed-up</a> 
一些有用的映射                                   <a href="tips.html#useful-mappings">useful-mappings</a> 
压缩帮助文件                                     <a href="tips.html#gzip-helpfile">gzip-helpfile</a> 
在一个窗口中执行外壳命令                         <a href="tips.html#shell-window">shell-window</a> 
十六进制编辑                                     <a href="tips.html#hex-editing">hex-editing</a> 
在自动命令中使用 <code class="special">&lt;&gt;</code> 记法                         <a href="tips.html#autocmd-%3C%3E">autocmd-&lt;&gt;</a> 
高亮匹配括号                                     <a href="tips.html#match-parens">match-parens</a> 
在当前窗口打开帮助                               <a href="tips.html#help-curwin">help-curwin</a> 

</section><hr class="doubleline" /><section class=inner>
<h4>编辑 C 程序                                             <b class="vimtag"> <a name="C-editing">C-editing</a> </b></h4>
Vim 里面有不少功能可以帮助你们编辑 C 程序。以下是一个概括，你们可以使用标签跳
转到具体的内容中去:

 <a href="usr_29.html#usr_29.txt">usr_29.txt</a>             用户手册中关于在程序的不同部分间移动的内容。
 <a href="usr_30.html#usr_30.txt">usr_30.txt</a>             用户手册中关于编辑程序的内容。
 <a href="indent.html#C-indenting">C-indenting</a>            输入时自动设置每行的缩进。
 <a href="change.html#%20">=</a>                      重新缩进一些行。
 <a href="change.html#format-comments">format-comments</a>        对注释进行排版。

 <a href="tagsrch.html#:checkpath">:checkpath</a>             显示所有被 (嵌套) 包含的文件。
 <a href="tagsrch.html#[i">[i</a>                     在当前和被包含的文件中查找光标所在的的标识符。
 <a href="tagsrch.html#[_CTRL-I">[_CTRL-I</a>               跳到 "[i" 的匹配。
 <a href="tagsrch.html#[I">[I</a>                     列出在当前和被包含的文件中匹配光标所在的标识符的行。
 <a href="tagsrch.html#[d">[d</a>                     在当前和被包含的文件中查找光标所在的标识符的宏定义。

 <a href="tagsrch.html#CTRL-]">CTRL-]</a>                 跳到光标所在的标签处 (例如: 函数的定义)。
 <a href="tagsrch.html#CTRL-T">CTRL-T</a>                 跳回执行 <code class="keystroke">CTRL-]</code> 命令前的地方。
 <a href="tagsrch.html#:tselect">:tselect</a>               从一连串匹配的标签中选出一个。

 <a href="pattern.html#gd">gd</a>                     跳到光标所在的局部变量的声明处。
 <a href="pattern.html#gD">gD</a>                     跳到光标所在的全局变量的声明处。

 <a href="editing.html#gf">gf</a>                     跳到光标所在的文件名表示的文件。

 <a href="motion.html#%">%</a>                      跳到匹配的 ()、<code class="special">{}</code>、[]、/* */、#if、#else、#endif 处。
 <a href="motion.html#[%2F">[/</a>                     跳到上一个注释开始的位置。
 <a href="motion.html#]%2F">]/</a>                     跳到下一个注释结束的位置。
 <a href="motion.html#[%23">[#</a>                     反向到未闭合的 #if、#ifdef 或 #else 处。
 <a href="motion.html#]%23">]#</a>                     正向到未闭合的 #else 或 #endif 处。
 <a href="motion.html#[(">[(</a>                     反向到未闭合的 '(' 处。
 <a href="motion.html#])">])</a>                     正向到未闭合的 ')' 处。
 <a href="motion.html#[{">[{</a>                     反向到未闭合的 '{' 处。
 <a href="motion.html#]}">]}</a>                     正向到未闭合的 '}' 处。

 <a href="motion.html#v_ab">v_ab</a>                   选中 "一个块" ("a block")，从 "[(" 至 "])"，含括号
 <a href="motion.html#v_ib">v_ib</a>                   选中 "内含块" ("inner block")，从 "[(" 至 "])"
 <a href="motion.html#v_aB">v_aB</a>                   选中 "一个大块" ("a Block")，从 "[{" 至 "]}"，含括号
 <a href="motion.html#v_iB">v_iB</a>                   选中 "内含大块" ("inner Block")，从 "[{" 至 "]}"

</section><hr class="doubleline" /><section class=inner>
<h4>查找使用标识符的地方                                    <b class="vimtag"> <a name="ident-search">ident-search</a> </b></h4>
你应该已经知道  <a href="tagsrch.html#tags">tags</a>  可以被用来跳转到定义函数和变量的地方。但是有时你希望跳转
到使用函数和变量的地方。可以用以下两种方法实现:
1. 使用  <a href="quickfix.html#:grep">:grep</a>  命令。这个应该可以在大多数 Unix 系统上工作，但是速度会比较慢
(因为它读取所有的文件)，并且只能在一个目录中搜索。
2. 使用 ID 工具集。这个速度比较快而且可以搜索多个目录。它使用一个数据库来存放
定位信息。你需要一些额外的程序来使它得以工作，并且你必须使数据库不断保持更新。

使用 GNU id 工具集 (id-tools):

你所需要的:
- 安装 GNU id 工具集 (mkid 是用来创建 ID 的，lid 是用来运行宏的)
- 一个在当前目录下名为 "ID" 的标识符数据库。你可以用外壳命令 "mkid file1 file2
  .." 来创建它。

把这些添加写你的 .vimrc 文件中: 
<code class="example">        map _u :call ID_search()&lt;Bar&gt;execute "/\\&lt;" .. g:word .. "\\&gt;"&lt;CR&gt;</code>
<code class="example">        map _n :n&lt;Bar&gt;execute "/\\&lt;" .. g:word .. "\\&gt;"&lt;CR&gt;</code>
<code class="example"></code>
<code class="example">        function! ID_search()</code>
<code class="example">          let g:word = expand("&lt;cword&gt;")</code>
<code class="example">          let x = system("lid --key=none " .. g:word)</code>
<code class="example">          let x = substitute(x, "\n", " ", "g")</code>
<code class="example">          execute "next " .. x</code>
<code class="example">        endfun</code>
<code class="example"></code>
使用的时候，把光标放在一个单词上，敲入 "_u"，然后 vim 会读入含有这个单词的文
件。使用 "n" 查找这个单词在相同文件中下一次的出现的地方。使用 "_n" 可以跳转到
下一个文件。

这些操作已经使用 id-utils-3.2 (这是位于距你最近的 gnu ftp 镜像服务器上的档案
名称) 测试通过了。

[这个的想法来自于 Andreas Kutschera]

</section><hr class="doubleline" /><section class=inner>
<h4>在 xterm 中切换屏幕                     <b class="vimtag"> <a name="xterm-screens">xterm-screens</a> </b> <b class="vimtag"> <a name="xterm-save-screen">xterm-save-screen</a> </b></h4>
(来源: comp.editors，作者: Juergen Weigert，回答一个问题的时候)

:&gt; 另一个问题就是退出 vim 后，屏幕内容就被留在那儿了，也就是说: 我刚刚正在查看
:&gt; (或编辑) 的内容就被留在屏幕上了。而我此前执行的命令 (例如: "ls") 的输出却不
:&gt; 见了，换而言之在滚屏缓冲区里不存在了。我知道有个办法可以在退出 vim 或其他仿
:&gt; vi 的编辑器的时候恢复屏幕内容，但是我不知道该如何操作。请帮助我，谢谢！
:
: 我认为可能有人可以回答这个问题。我认为 vim 和 vi 在某个特定的 xterm 安装下和
: 别的程序一样工作。

他们并不一定完全相同，因为这牵扯到一个 termcap 对 terminfo 的问题。你们应该知
道针对一种特定的终端，有两种数据库可以用来描述它的属性: termcap 和 terminfo。
当它们中的条目不同，而且以上问题中的一个程序使用 terminfo，另一个使用 termcap
时，两个程序会出现差异 (请参见:  <a href="various.html#+terminfo">+terminfo</a> )。

在你的问题中，你可能需要以下的控制序列: ^[[?47h 和 ^[[?47l。他们用来在 xterm
备用和主屏幕缓冲区中切换。一个快速的临时解决方案使用如下的命令序列 
<code class="example">        echo -n "^[[?47h"; vim ... ; echo -n "^[[?47l"</code>
这可能就是你所需要的。(我用符号 ^[ 表示 ESC 字符，往后你还会看到数据库使用 \E
来表示它)。

在启动的时候，vim 把 termcap 中变量 ti (terminfo:smcup) 的值回显在终端上。退出
的时候，它回显 te (terminfo: rmcup) 的值。这样一来，这两个变量正好处于以上所述
的控制序列应该执行的位置。

把你的 xterm termcap 条目 (在 /etc/termcap 中) 和 xterm terminfo 条目 (用
"infocmp -C xterm" 得到) 比较一下。两者应该都会有与下面类似的条目: 
<code class="example">        :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:</code>
<code class="example"></code>
附: 如果你发现了任何差异，那么最好让某人 (或许是你的系统管理员) 彻底地检查一下
    termcap 和 terminfo 的一致性。

<code class="note">备注</code> 1: 如果你在 feature.h 中定义了 FEAT_XTERM_SAVE 之后又重新编译了 Vim，那么
内置的 xterm 会有上述的 "te" 和 "ti" 条目。

<code class="note">备注</code> 2: 如果你希望禁止屏幕切换，并且不希望改变你的 termcap，你可以在 .vimrc 文
件中加入这一行: 
<code class="example">        :set t_ti= t_te=</code>
<code class="example"></code>
</section><hr class="doubleline" /><section class=inner>
<h4>在插入模式下滚屏                                        <b class="vimtag"> <a name="scroll-insert">scroll-insert</a> </b></h4>
如果你处于插入模式下并且想看恰好在屏幕范围以外的一些东西，可用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-E</code>
和 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-Y</code> 来滚屏。
                                                 <a href="insert.html#i_CTRL-X_CTRL-E">i_CTRL-X_CTRL-E</a> 

更简便地，可用以下映射: 
<code class="example">        :inoremap &lt;C-E&gt; &lt;C-X&gt;&lt;C-E&gt;</code>
<code class="example">        :inoremap &lt;C-Y&gt; &lt;C-X&gt;&lt;C-Y&gt;</code>
(逐字敲入这些字符，并确认 '&lt;' 标志位不在 <a href="options.html#'cpoptions'">'cpoptions'</a> 选项中)。
不过这样你就不能使用从光标上一行/下一行拷贝文字的功能了  <a href="insert.html#i_CTRL-E">i_CTRL-E</a> 。

还可以考虑把 <a href="options.html#'scrolloff'">'scrolloff'</a> 设置得大一些，这样就总能看到光标附近的上下文了。如果
<a href="options.html#'scrolloff'">'scrolloff'</a> 的值大于窗口高度的一半，在向上或向下移动光标时，文字会上下卷动，但
是光标会始终停留在屏幕中间的位置。

</section><hr class="doubleline" /><section class=inner>
<h4>平滑滚屏                                                <b class="vimtag"> <a name="scroll-smooth">scroll-smooth</a> </b></h4>
如果你希望你的滚屏更加平滑一些，你可以使用以下的映射: 
<code class="example">        :map &lt;C-U&gt; &lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;&lt;C-Y&gt;</code>
<code class="example">        :map &lt;C-D&gt; &lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;&lt;C-E&gt;</code>
<code class="example"></code>
(逐字敲入这些字符，并确认 '&lt;' 标志位不在 <a href="options.html#'cpoptions'">'cpoptions'</a> 选项中)。

</section><hr class="doubleline" /><section class=inner>
<h4>纠正普通的录入错误                                      <b class="vimtag"> <a name="type-mistakes">type-mistakes</a> </b></h4>
如果有一些单词你总是敲错，你可以使用缩写来改正它们。例如: 
<code class="example">        :ab teh the</code>
<code class="example">        :ab fro for</code>
<code class="example"></code>
</section><hr class="doubleline" /><section class=inner>
<h4>统计单词数、行数等                                      <b class="vimtag"> <a name="count-items">count-items</a> </b></h4>
如果需要统计缓冲区中一个模式 (pattern) 出现的频率，使用 substitute 命令并加入
'n' 标志位以避免实际的替代。Vim 报告的已替代的数目就是模式出现的次数。例: 
<code class="example"></code>
<code class="example">        :%s/./&amp;/gn              字符数</code>
<code class="example">        :%s/\i\+/&amp;/gn           单词数</code>
<code class="example">        :%s/^//n                行数</code>
<code class="example">        :%s/the/&amp;/gn            任何地方出现的 "the"</code>
<code class="example">        :%s/\&lt;the\&gt;/&amp;/gn        作为单词出现的 "the"</code>
<code class="example"></code>
此时你可能希望复位 <a href="options.html#'hlsearch'">'hlsearch'</a> 或者使用 ":nohlsearch"。
如果你希望没有匹配的时候不报错，加上标志位 'e'。

另一种办法就是在可视模式下使用  <a href="editing.html#v_g_CTRL-G">v_g_CTRL-G</a> 。

如果你想在多个文件中查找匹配，用  <a href="quickfix.html#:vimgrep">:vimgrep</a> 。

                                                        <b class="vimtag"> <a name="count-bytes">count-bytes</a> </b>
如果你想统计字节数，可以这样做:

        可视选择那些字符 (列块选择也可以)
        使用 "y" 来拷贝这些字符
        使用 strlen() 函数: 
<code class="example">                :echo strlen(@")</code>
这里换行符被当做一个字节。

</section><hr class="doubleline" /><section class=inner>
<h4>恢复光标位置                                            <b class="vimtag"> <a name="restore-position">restore-position</a> </b></h4>
有时你希望写一个在文件中的其他地方做一些修改然后恢复光标的位置且不滚动文本的映
射。例如，要修改文件中的日期标记，可以这样: 
<code class="example"></code>
<code class="example">   :map &lt;F2&gt; msHmtgg/Last [cC]hange:\s*/e+1&lt;CR&gt;"_D"=strftime("%Y %b %d")&lt;CR&gt;p'tzt`s</code>
<code class="example"></code>
分解出保存位置的命令:
        ms      把光标位置存放在位置标记 's' 中
        H       跳转到窗口的顶端
        mt      把这个位置存放在位置标记 't' 中

分解出恢复位置的命令:
        't      跳转到先前位于窗口顶端的那一行
        zt      滚屏，使这一行位于窗口的顶端
        `s      跳转到最初光标的位置

更高级的方法见  <a href="builtin.html#winsaveview()">winsaveview()</a>  和  <a href="builtin.html#winrestview()">winrestview()</a> 。

</section><hr class="doubleline" /><section class=inner>
<h4>文件更名                                                <b class="vimtag"> <a name="rename-files">rename-files</a> </b></h4>
假如我有一个目录，里面有如下的文件 (目录是随机选取的):

buffer.c
charset.c
digraph.c
...

现在我希望把 *.c 更名为 *.bla。我可以这样做: 
<code class="example"></code>
<code class="example">        $ vim</code>
<code class="example">        :r !ls *.c</code>
<code class="example">        :%s/\(.*\).c/mv &amp; \1.bla</code>
<code class="example">        :w !sh</code>
<code class="example">        :q!</code>
<code class="example"></code>
</section><hr class="doubleline" /><section class=inner>
<h4>更改多个文件中的一个名字                                <b class="vimtag"> <a name="change-name">change-name</a> </b></h4>
使用脚本文件在若干文件中更改一个名字的示例:

        创建文件 "subs.vim"，包含替代命令和 :update 命令: 
<code class="example">                :%s/Jones/Smith/g</code>
<code class="example">                :%s/Allen/Peter/g</code>
<code class="example">                :update</code>

        在所有你要改动的文件上执行 Vim，然后为每个参数执行该脚本: 
<code class="example"></code>
<code class="example">                vim *.let</code>
<code class="example">                argdo source subs.vim</code>
<code class="example"></code>
参见  <a href="editing.html#:argdo">:argdo</a> 。

</section><hr class="doubleline" /><section class=inner>
<h4>加速外部命令的执行                                      <b class="vimtag"> <a name="speed-up">speed-up</a> </b></h4>
在某些情况下，外部命令执行起来非常地慢。而且还会减慢 Unix 上的通配符扩展。这儿
有一些可以加快速度的建议:

如果你的 .cshrc 文件 (根据你使用的外壳，文件名可能不同) 非常地长，你应该把它分
割成两节: 需要和用户交互的、无需和用户交互的 (经常被称作二级外壳)。当你在 Vim
中执行一个类似 ":!ls" 的命令时，你就不需要和用户交互的那一部分 (例如: 设置提示
符)。把那些不必要的部分放到下面这些行后面去: 
<code class="example"></code>
<code class="example">        if ($?prompt == 0) then</code>
<code class="example">                exit 0</code>
<code class="example">        endif</code>
<code class="example"></code>
另一个办法是在 <a href="options.html#'shell'">'shell'</a> 选项中包含 "-f" 参数，例如: 
<code class="example"></code>
<code class="example">        :set shell=csh\ -f</code>
<code class="example"></code>
(这儿的反斜杠是必需的，这样才能在选项中表示一个空格)。
这样就会使 csh 完全跳过 .cshrc 文件。不过这样可能会造成一些程序不能正常运行。

</section><hr class="doubleline" /><section class=inner>
<h4>有用的映射                                      <b class="vimtag"> <a name="useful-mappings">useful-mappings</a> </b></h4>
这里提供一些部分人喜欢使用的映射。

                                                        <b class="vimtag"> <a name="map-backtick">map-backtick</a> </b>  
<code class="example">        :map ' `</code>
使得单引号和 ' 一样工作。把光标移动到一个位置标记所在的列，而不是那一行的第一
个非空白字符。

                                                        <b class="vimtag"> <a name="emacs-keys">emacs-keys</a> </b>
要在命令行上实现 Emacs 风格的编辑操作: 
<code class="example">        " 至行首</code>
<code class="example">        :cnoremap &lt;C-A&gt;         &lt;Home&gt;</code>
<code class="example">        " 后退一个字符</code>
<code class="example">        :cnoremap &lt;C-B&gt;         &lt;Left&gt;</code>
<code class="example">        " 删除光标所在的字符</code>
<code class="example">        :cnoremap &lt;C-D&gt;         &lt;Del&gt;</code>
<code class="example">        " 至行尾</code>
<code class="example">        :cnoremap &lt;C-E&gt;         &lt;End&gt;</code>
<code class="example">        " 前进一个字符</code>
<code class="example">        :cnoremap &lt;C-F&gt;         &lt;Right&gt;</code>
<code class="example">        " 取回较新的命令行</code>
<code class="example">        :cnoremap &lt;C-N&gt;         &lt;Down&gt;</code>
<code class="example">        " 取回以前 (较旧的) 命令行</code>
<code class="example">        :cnoremap &lt;C-P&gt;         &lt;Up&gt;</code>
<code class="example">        " 后退一个单词</code>
<code class="example">        :cnoremap &lt;Esc&gt;&lt;C-B&gt;    &lt;S-Left&gt;</code>
<code class="example">        " 前进一个单词</code>
<code class="example">        :cnoremap &lt;Esc&gt;&lt;C-F&gt;    &lt;S-Right&gt;</code>
<code class="example"></code>
<code class="note">备注</code>: 前提条件是 '&lt;' 标志位不在 <a href="options.html#'cpoptions'">'cpoptions'</a> 选项中。 <a href="intro.html#%3C%3E">&lt;&gt;</a> 

                                                        <b class="vimtag"> <a name="format-bullet-list">format-bullet-list</a> </b>
这个映射可以排版任何带符号的 (bullet) 列表，不过它需要在每一个条目的上下都各有
一个空行。使用表达式命令，以便对映射的部分进行注释: 
<code class="example"></code>
<code class="example">        :let m =     ":map _f  :set ai&lt;CR&gt;"   " 需要置位 'autoindent'</code>
<code class="example">        :let m ..= "{O&lt;Esc&gt;"                  " 在项目上面加入空行</code>
<code class="example">        :let m ..= "}{)^W"                    " 跳转到 bullet 之后的文本</code>
<code class="example">        :let m ..= "i     &lt;CR&gt;     &lt;Esc&gt;"     " 为缩进加空格</code>
<code class="example">        :let m ..= "gq}"                      " 排版 bullet 之后的文本</code>
<code class="example">        :let m ..= "{dd"                      " 删除空行</code>
<code class="example">        :let m ..= "5lDJ"                     " 把文本放到 bullet 之后</code>
<code class="example">        :execute m                            |" 定义这个 mapping</code>
<code class="example"></code>
(<code class="special">&lt;&gt;</code> 记法  <a href="intro.html#%3C%3E">&lt;&gt;</a> 。<code class="note">注意</code> 必须按照字面逐个输入。^W 是 "^" 和 "W"，而不是 <code class="keystroke">CTRL-W</code>。如
果 '&lt;' 标志位不在 <a href="options.html#'cpoptions'">'cpoptions'</a> 选项中，你可以把这些拷贝/粘贴代码给 Vim 执行。)

<code class="note">注意</code> 最后一个注释以 |" 开始，因为 ":execute" 不能直接识别一个注释。

你还需要把 <a href="options.html#'textwidth'">'textwidth'</a> 设置成一个非 0 值，例如: 
<code class="example">        :set tw=70</code>
<code class="example"></code>
以下这个映射可以达到同样的效果，不过它从第一行获得列表的缩进 (<code class="note">备注</code>: 这个映射其
实只有一行，其中有很多空格): 
<code class="example">        :map _f :set ai&lt;CR&gt;}{a                                                          &lt;Esc&gt;WWmmkD`mi&lt;CR&gt;&lt;Esc&gt;kkddpJgq}'mJO&lt;Esc&gt;j</code>

                                                        <b class="vimtag"> <a name="collapse">collapse</a> </b>
这两个映射可以把一连串的空行 (;b) 或空白行 (;n) 压缩到一行 
<code class="example">    :map ;b   GoZ&lt;Esc&gt;:g/^$/.,/./-j&lt;CR&gt;Gdd</code>
<code class="example">    :map ;n   GoZ&lt;Esc&gt;:g/^[ &lt;Tab&gt;]*$/.,/[^ &lt;Tab&gt;]/-j&lt;CR&gt;Gdd</code>
<code class="example"></code>
</section><hr class="doubleline" /><section class=inner>
<h4>压缩帮助文件                                            <b class="vimtag"> <a name="gzip-helpfile">gzip-helpfile</a> </b></h4>
对于那些磁盘空间极度紧张的人来说，你们可以压缩帮助文件。这样会使得查看帮助文
件时稍微慢一点，并且需要 "gzip" 这个程序的支持。

(1) 压缩所有帮助文件: "gzip doc/*.txt"。

(2) 编辑文件 "doc/tags"，用 ".txt.gz" 替换 ".txt": 
<code class="example">        :%s=\(\t.*\.txt\)\t=\1.gz\t=</code>
<code class="example"></code>
(3) 把这一行加入到你的 vimrc 文件中: 
<code class="example">        set helpfile={dirname}/help.txt.gz</code>
<code class="example"></code>
这儿 <code class="special">{dirname}</code> 是存放帮助文件的目录。 <a href="pi_gzip.html#gzip">gzip</a>  插件会负责解压这些文件。
如果其它 Vim 文件和存放压缩帮助的 "doc" 目录所在的位置不一致，要确保
$VIMRUNTIME 设为存放那些 Vim 文件的目录。参见:  <a href="starting.html#$VIMRUNTIME">$VIMRUNTIME</a> 。

</section><hr class="doubleline" /><section class=inner>
<h4>在一个窗口中执行外壳命令                                <b class="vimtag"> <a name="shell-window">shell-window</a> </b></h4>
见  <a href="terminal.html#terminal">terminal</a> 。

另一个方法是用 "splitvt" 程序把你的终端屏幕或显示窗口进行分割。在一些 ftp 服务
器上你可以找到这个工具。Sam Lantinga &lt;slouken@cs.ucdavis.edu&gt; 对此了解颇多。

另一种办法是使用在 BSD Unix 系统上出现的 "window" 命令，它支持多个重叠的窗口。
或者使用最先出现在 www.uni-erlangen.de 上的 "screen" 程序，它支持窗口栈。

</section><hr class="doubleline" /><section class=inner>
<h4>十六进制编辑                                    <b class="vimtag"> <a name="hex-editing">hex-editing</a> </b> <b class="vimtag"> <a name="using-xxd">using-xxd</a> </b></h4>
请看用户手册的第  <a href="usr_23.html#23.4">23.4</a>  节。

如果你用一些专门的扩展名来命名二进制文件 (诸如 exe，bin 等等)，你会发现以下在
&lt;.vimrc&gt; 文件中使用的一些命令在自动处理这些文件时非常有用。你可以用你希望编辑
的文件扩展名 (用逗号分隔) 替换以下的 "*.bin": 
<code class="example"></code>
<code class="example">        " vim -b : edit binary using xxd-format!</code>
<code class="example">        augroup Binary</code>
<code class="example">          au!</code>
<code class="example">          au BufReadPre  *.bin let &amp;bin=1</code>
<code class="example">          au BufReadPost *.bin if &amp;bin | %!xxd</code>
<code class="example">          au BufReadPost *.bin set ft=xxd | endif</code>
<code class="example">          au BufWritePre *.bin if &amp;bin | %!xxd -r</code>
<code class="example">          au BufWritePre *.bin endif</code>
<code class="example">          au BufWritePost *.bin if &amp;bin | %!xxd</code>
<code class="example">          au BufWritePost *.bin set nomod | endif</code>
<code class="example">        augroup END</code>
<code class="example"></code>
</section><hr class="doubleline" /><section class=inner>
<h4>在自动命令中使用 <code class="special">&lt;&gt;</code> 记法                                <b class="vimtag"> <a name="autocmd-%3C%3E">autocmd-&lt;&gt;</a> </b></h4>
在自动命令的参数中，不能识别 <code class="special">&lt;&gt;</code> 记法。为避免使用特殊的字符，你可以使用一个可以
自我毁灭的映射来得到 <code class="special">&lt;&gt;</code> 记法，然后从自动命令中调用这个映射。举例如下:

                                                <b class="vimtag"> <a name="map-self-destroy">map-self-destroy</a> </b>  
<code class="example"> " 此命令自动把文件名加入到菜单列表中。</code>
<code class="example"> " 它使用了一个可以自我毁灭的映射！</code>
<code class="example"> " 1. 用缓冲区中的一行把文件名中的点 ('dots') 转换成 \.</code>
<code class="example"> " 2. 把该行存放在寄存器 '"' 中</code>
<code class="example"> " 3. 把该名字加入缓冲区菜单列表</code>
<code class="example"> " 警 告: 这会有些副作用，比如: 覆盖当前的寄存器内容和删除任何 "i" 命令的映射</code>
<code class="example"> "</code>
<code class="example"> autocmd BufNewFile,BufReadPre * nmap i :nunmap i&lt;CR&gt;O&lt;C-R&gt;%&lt;Esc&gt;:.g/\./s/\./\\./g&lt;CR&gt;0"9y$u:menu Buffers.&lt;C-R&gt;9 :buffer &lt;C-R&gt;%&lt;C-V&gt;&lt;CR&gt;&lt;CR&gt;</code>
<code class="example"> autocmd BufNewFile,BufReadPre * normal i</code>
<code class="example"></code>
另一个或许更好一些的办法就是使用 ":execute" 命令。在字符串中，你可以通过在 <code class="special">&lt;&gt;</code>
记法前面加一个反斜杠的方法来使用它。别忘了加倍已经存在的反斜杠的数目以及在 '"'
前面放一个反斜杠。 
<code class="example"></code>
<code class="example">  autocmd BufNewFile,BufReadPre * exe "normal O\&lt;C-R&gt;%\&lt;Esc&gt;:.g/\\./s/\\./\\\\./g\&lt;CR&gt;0\"9y$u:menu Buffers.\&lt;C-R&gt;9 :buffer \&lt;C-R&gt;%\&lt;C-V&gt;\&lt;CR&gt;\&lt;CR&gt;"</code>
<code class="example"></code>
为了建立一个真正的缓冲区菜单，需要用到用户函数 (参见  <a href="userfunc.html#:function">:function</a> )，不过那里不
使用 <code class="special">&lt;&gt;</code> 记法，所以失去了在这里举例的意义。

</section><hr class="doubleline" /><section class=inner>
<h4>高亮匹配括号                                                    <b class="vimtag"> <a name="match-parens">match-parens</a> </b></h4>
本例演示一些高级技巧的用法:
- 使用  <a href="autocmd.html#CursorMoved">CursorMoved</a>  自动命令事件
- 使用  <a href="builtin.html#searchpairpos()">searchpairpos()</a>  查找匹配括号
- 使用  <a href="builtin.html#synID()">synID()</a>  检测光标是否在字符串或注释里
- 使用  <a href="pattern.html#:match">:match</a>  高亮一些内容
- 使用  <a href="pattern.html#pattern">pattern</a>  匹配文件的特定位置。

它应该被放在 Vim 脚本里，因为使用了局部于脚本的变量。除非光标起始于字符串或者
注释的内部，它会跳过字符串或注释里的匹配。这需要语法高亮的支持。

 <a href="pi_paren.html#matchparen">matchparen</a>  插件使用的是一个稍稍改进的版本。

<code class="example">        let s:paren_hl_on = 0</code>
<code class="example">        function s:Highlight_Matching_Paren()</code>
<code class="example">          if s:paren_hl_on</code>
<code class="example">            match none</code>
<code class="example">            let s:paren_hl_on = 0</code>
<code class="example">          endif</code>
<code class="example"></code>
<code class="example">          let c_lnum = line('.')</code>
<code class="example">          let c_col = col('.')</code>
<code class="example"></code>
<code class="example">          let c = getline(c_lnum)[c_col - 1]</code>
<code class="example">          let plist = split(&amp;matchpairs, ':\|,')</code>
<code class="example">          let i = index(plist, c)</code>
<code class="example">          if i &lt; 0</code>
<code class="example">            return</code>
<code class="example">          endif</code>
<code class="example">          if i % 2 == 0</code>
<code class="example">            let s_flags = 'nW'</code>
<code class="example">            let c2 = plist[i + 1]</code>
<code class="example">          else</code>
<code class="example">            let s_flags = 'nbW'</code>
<code class="example">            let c2 = c</code>
<code class="example">            let c = plist[i - 1]</code>
<code class="example">          endif</code>
<code class="example">          if c == '['</code>
<code class="example">            let c = '\['</code>
<code class="example">            let c2 = '\]'</code>
<code class="example">          endif</code>
<code class="example">          let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' ..</code>
<code class="example">                \ '=~?  "string\\|comment"'</code>
<code class="example">          execute 'if' s_skip '| let s_skip = 0 | endif'</code>
<code class="example"></code>
<code class="example">          let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip)</code>
<code class="example"></code>
<code class="example">          if m_lnum &gt; 0 &amp;&amp; m_lnum &gt;= line('w0') &amp;&amp; m_lnum &lt;= line('w$')</code>
<code class="example">            exe 'match Search /\(\%' .. c_lnum .. 'l\%' .. c_col ..</code>
<code class="example">                  \ 'c\)\|\(\%' .. m_lnum .. 'l\%' .. m_col .. 'c\)/'</code>
<code class="example">            let s:paren_hl_on = 1</code>
<code class="example">          endif</code>
<code class="example">        endfunction</code>
<code class="example"></code>
<code class="example">        autocmd CursorMoved,CursorMovedI * call s:Highlight_Matching_Paren()</code>
<code class="example">        autocmd InsertEnter * match none</code>


</section><hr class="doubleline" /><section class=inner>
<h4>在当前窗口打开帮助                                              <b class="vimtag"> <a name="help-curwin">help-curwin</a> </b></h4>
缺省在分割窗口打开帮助。如果喜欢在当前窗口打开帮助，可用下面的定制命令
 <code class="badlink">:HelpCurwin</code> :

<code class="example">        command -bar -nargs=? -complete=help HelpCurwin execute s:HelpCurwin(&lt;q-args&gt;)</code>
<code class="example">        let s:did_open_help = v:false</code>
<code class="example"></code>
<code class="example">        function s:HelpCurwin(subject) abort</code>
<code class="example">          let mods = 'silent noautocmd keepalt'</code>
<code class="example">          if !s:did_open_help</code>
<code class="example">            execute mods .. ' help'</code>
<code class="example">            execute mods .. ' helpclose'</code>
<code class="example">            let s:did_open_help = v:true</code>
<code class="example">          endif</code>
<code class="example">          if !getcompletion(a:subject, 'help')-&gt;empty()</code>
<code class="example">            execute mods .. ' edit ' .. &amp;helpfile</code>
<code class="example">            set buftype=help</code>
<code class="example">          endif</code>
<code class="example">          return 'help ' .. a:subject</code>
<code class="example">        endfunction</code>



 vim:tw=78:ts=8:noet:ft=help:norl:
</section>
</article>
<footer>
Generated by vim2html
</footer>
</body>
</html>
